package org.web2024.cnofig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.web2024.exception.AccessDeniedHandlerImp;
import org.web2024.exception.AuthenticationEntryPointImp;
import org.web2024.fliter.JwtAuthenticationTokenFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig{

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    private AuthenticationEntryPointImp authenticationEntryPointImp;
    @Autowired
    private AccessDeniedHandlerImp accessDeniedHandlerImp;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder() ;
        };

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 禁用CSRF保护，因为我们的应用将使用基于token的身份验证，不需要session
        http.csrf(CsrfConfigurer::disable)
                // 配置会话管理策略，因为我们使用的是无状态的身份验证方法，所以不需要创建会话
                .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 基于token，不需要session
                // 配置请求授权规则
                .authorizeHttpRequests((authz) -> authz
                        // 放行/login路径的请求，允许任何人访问，用于用户登录
                        .requestMatchers("/login").permitAll() // 放行api
                        //.requestMatchers("/admin/**").hasRole("admin")
                        //.requestMatchers("/student/**").hasRole("student")
                        //.requestMatchers("/teacher/**").hasRole("teacher")
                        // 放行所有OPTIONS类型的请求，通常用于CORS预检请求
                        .requestMatchers(HttpMethod.OPTIONS).permitAll()
                        // 所有其他请求都需要经过身份验证
                        .anyRequest().authenticated()
                )
                // 在UsernamePasswordAuthenticationFilter之前添加JWT身份验证过滤器
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        // 配置异常处理，包括未认证和访问拒绝的情况
        http.exceptionHandling(exceptionHandlingConfigurer ->
                exceptionHandlingConfigurer.authenticationEntryPoint(authenticationEntryPointImp)
                        .accessDeniedHandler(accessDeniedHandlerImp));
        return http.build();

    }

    @Bean//认证管理器
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authconfiguration) throws Exception {
        return authconfiguration.getAuthenticationManager();
    }

}
